package com.wwdx.controller.rest;

import com.wwdx.model.WwdxOpenAuthModel;
import com.wwdx.service.WwdxOpenAuthServiceI;
import com.wwdx.service.impl.FirstWxOpenService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author liguoliang
 * @date 2018-09-17 19:15:27
 */
@RestController
@RequestMapping("/notify")
@ApiIgnore
public class OpenNotifyController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private FirstWxOpenService wxOpenService;
    @Resource
    private WwdxOpenAuthServiceI wwdxOpenAuthService;

    @RequestMapping("/receive_ticket")
    public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
                                @RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
                                @RequestParam(name = "encrypt_type", required = false) String encType,
                                @RequestParam(name = "msg_signature", required = false) String msgSignature) {
        this.logger.info(
                "\n接收微信请求：[signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                signature, encType, msgSignature, timestamp, nonce, requestBody);
        if (!wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        //aes加密的消息
        WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody,
                wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
        this.logger.info("\n消息解密后内容为：\n{} ", inMessage.toString());
        //更新授权状态
        String infoType = inMessage.getInfoType(),unauthorized = "unauthorized";
        if (unauthorized.equalsIgnoreCase(infoType)){
            WwdxOpenAuthModel wwdxOpenAuthModel = wwdxOpenAuthService.getByAppId(inMessage.getAuthorizerAppid());
            if (wwdxOpenAuthModel != null){
                wwdxOpenAuthService.delete(wwdxOpenAuthModel);
            }
        }
        try {
            String out = wxOpenService.getWxOpenComponentService().route(inMessage);
            this.logger.info("\n组装回复信息：{}", out);
        } catch (WxErrorException e) {
            this.logger.error("receive_ticket", e);
        }
        return "success";
    }

    @RequestMapping("{appId}/callback")
    public void callback(@RequestBody(required = false) String requestBody,
                         @PathVariable("appId") String appId,
                         String signature, String timestamp, String nonce, String openid,
                         @RequestParam("encrypt_type") String encType,
                         @RequestParam("msg_signature") String msgSignature, HttpServletResponse response) throws IOException {
        this.logger.info(
                "\n接收微信请求：[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
        if (!wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        String out = "";
        // aes加密的消息
        WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody,
                wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
        this.logger.debug("\n消息解密后内容为：\n{} ", inMessage.toString());
        WxMpXmlOutMessage outMessage = wxOpenService.getWxOpenMessageRouter().route(inMessage, appId);
        if(outMessage != null){
            out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage());
        }
        response.getWriter().print(out);
    }
}